﻿/*****************************************************************************//*!
* file  : cantask.c
* creat : apleilx
* data  : 2017/11/05
*******************************************************************************/

#include "os_obj.h"
#include "pincfg.h"
#include "sys_init.h"
#include "com_obj.h"
#include "bsp_hal.h"
#include "can_quene.h"

#define _CANTASK_MODULE_
#include "can_task.h"


timer_pulse_type mb_pulse;

void can_filter_cfg(void);
void can_test(void);

void can2_quene_init(void);
void can1_quene_init(void);
void can_event_send(uint16_t event);

typedef struct
{
	simp_can_frame_type f_buff[2];
	uint8_t can1_tx_req;
	uint8_t can2_tx_req;
	
	uint32_t can1_cmd_dat[32];
	uint32_t can1_sync_cmd_dat[32];
	
	uint32_t baud_cal_us;
	uint32_t can_task_cnt;
	uint32_t can_send_event;
} can_test_type;

can_test_type can_tst_obj;

can_baud_cal_type can_baud;

extern simp_can_frame_ctr_type can1_quene;
extern simp_can_frame_ctr_type can2_quene;

void can1_handle_callback(uint8_t err_st, struct simp_can_frame_ctr_str *quene);

/*******************************************************************************
* @brief  task_can
* \param[in] thread_input : argv
* \retval: none
*******************************************************************************/
void task_can(void * thread_input)
{
	uint32_t time_start;

	(void)thread_input;

	can_baud.baud_set = 9600;
	can_baud.bs1_max = 16;
	can_baud.bs2_max = 8;
	can_baud.sjw_max = 4;
	can_baud.div_max = 128;

	pulse_init(&mb_pulse, app_tick_get());
	
	can1_quene_init();
	can2_quene_init();
	
	can_filter_cfg();
	
	while (1)
	{
		ULONG event_rcv;
		UINT os_err;
		
		pulse_create(&mb_pulse, app_tick_get());
		
		can_test();

		can_baud.clk = 96000000;

		time_start = app_tick_us_get();
		can_buad_cal(&can_baud);
		can_tst_obj.baud_cal_us = app_tick_us_get() - time_start;

		if(mb_pulse.bPulse_1s)
		{
			//can_tst_obj.can1_tx_req = 1;
			//can_tst_obj.can2_tx_req = 1;
		}
		if(mb_pulse.bPulse_1s)
		{
			//can_tst_obj.can1_tx_req = 1;
			//can_tst_obj.can2_tx_req = 1;
		}
		
		if(mb_pulse.bPulse_500ms)
		{
			loop(32)
			{
				can_tst_obj.can1_cmd_dat[index] = dword_bmake(index*4+3, index*4+2,index*4+1,index*4);
				can_tst_obj.can1_sync_cmd_dat[index] = dword_bmake(index*4, index*4+1,index*4+2,index*4+3);
			}
			
		}
		
		can2_quene.cmd_exe_time_interval = 250;
		can1_quene.cmd_exe_time_interval = 250;
		
		can1_quene.os_event_send = can_event_send;
		can2_quene.os_event_send = can_event_send;
		
		can_tst_obj.can_task_cnt++;
		
		if(mb_pulse.bPulse_1s)
		{
			can_dbg_print("can1 send: %-10d, can2 receive: %-10d  #### can2 send: %-10d, can1 receive: %-10d @ (%d) -- %d\n", 
				can1_quene.tx_cnt,
				can2_quene.rx_cnt,  
				can2_quene.tx_cnt,
				can1_quene.rx_cnt,  
				app_tick_get(),
				can_tst_obj.can_task_cnt
			);
		}
		
		
		can1_quene.ack_master = 1;
		can1_quene.cmd_handle_callback = can1_handle_callback;
		//simp_can_cmd_poll_ack(&can1_quene);
		simp_can_cmd_poll_mute(&can1_quene, 0);
		// 设置从机应答ID
		simp_can_cmd_slave_ack_id(&can2_quene, 0x00FF0000, 0x00660000);
		//simp_can_cmd_poll_ack(&can2_quene);	
		simp_can_cmd_poll_mute(&can2_quene, 0);	
		
		os_err = tx_event_flags_get(os_obj.eid_can, 0xFFFF, TX_OR_CLEAR, &event_rcv, 2000);
		
		if(TX_SUCCESS == os_err)
		{
			if(event_rcv & SIMP_CAN_OS_EVENT_INTERVAL)
			{
				can_dbg_print("@< %d ms >::EVENT:  INTERVAL\n", app_tick_get());
			}
			if(event_rcv & SIMP_CAN_OS_EVENT_RCV)
			{
				can_dbg_print("@< %d ms >::EVENT:  RCV\n", app_tick_get());
			}
			if(event_rcv & SIMP_CAN_OS_EVENT_ACK_TIMEOUT)
			{
				can_dbg_print("@< %d ms >::EVENT:  ACK TIMEOUT\n", app_tick_get());
			}
			if(event_rcv & SIMP_CAN_OS_EVENT_SYNC_CMD_RDY)
			{
				can_dbg_print("@< %d ms >::EVENT:  SYNC CMD READY\n", app_tick_get());
			}
			if(event_rcv & SIMP_CAN_OS_EVENT_SYNC_CMD_NOUSE)
			{
				can_dbg_print("@< %d ms >::EVENT:  SYNC CMD NOUSE\n", app_tick_get());
			}
		}
	}
}

/*******************************************************************************
* @brief  can receive and send
* \param[in] none
* \retval: none
*******************************************************************************/
void can_test(void)
{
	simp_can_cmd_type cmd;
	
	cmd.dat = can_tst_obj.can1_cmd_dat;
	cmd.id_mode = SIMP_CAN_ID_MODE_EXT;
	cmd.id = 0x660300;
	cmd.len = 16;
	cmd.remot = 0;
	cmd.sub_addr = 1024;
	
	simp_can_stc_cmd_req(&can1_quene, 0, &cmd);
	cmd.id = 0x660320;
	//simp_can_stc_cmd_req(&can1_quene, 3, &cmd);

	if(mb_pulse.bPulse_1s)
	{
		cmd.dat = can_tst_obj.can1_sync_cmd_dat;
		cmd.id = 0x660100;
		cmd.len = 44;
		simp_can_sync_cmd_req(&can1_quene, &cmd);
		
		cmd.id = 0x660120;
		cmd.dat = can_tst_obj.can1_cmd_dat;
		//simp_can_sdat_cmd_exe(&can1_quene, &cmd, 0);
	}

	//can2 send
	cmd.id = 0x330280;
	//simp_can_stc_cmd_req(&can2_quene, 1, &cmd);
	
	if (can_tst_obj.can2_tx_req)
	{
		can_tst_obj.can2_tx_req --;	
		
		cmd.dat = can_tst_obj.can1_cmd_dat;
		cmd.id_mode = SIMP_CAN_ID_MODE_EXT;
		cmd.id = 0x330200;
		cmd.len = 12;
		cmd.remot = 0;
		//simp_can_sync_cmd_req(&can2_quene, &cmd);
	}
}

void can1_handle_callback(volatile uint8_t err_st, struct simp_can_frame_ctr_str *quene)
{
	volatile char brkp;
	
	if(0 == err_st)
	{
		can_dbg_print("@%8d::CAN1 CMD EXE OK! \n", app_tick_get());
		brkp+=1;
	}
	else if(SIMP_CAN_EXE_MODE_SYNC_ACK_TIMEOUT == err_st)
	{
		can_dbg_print("@%8d::CAN1 CMD EXE ERROR < %s >-> id = %08x \n", 
					  app_tick_get(),
					  "TIMEOUT",
				   quene->cmd_exe_now.id);
		brkp+=2;
	}
	else
	{
		can_dbg_print("@%8d::CAN1 CMD EXE ERROR < %s >-> id = %08x, fcnt=%d \n",
					  app_tick_get(),
					  "ACK ERR",
				  quene->cmd_exe_now.id, quene->rx_frame[quene->rx_site_read].dat[0].v[0]);
		brkp+=3;
	}
}


void can_event_send(uint16_t event)
{
	if(event == SIMP_CAN_OS_EVENT_INTERVAL)
		can_tst_obj.can_send_event++;
	
	tx_event_flags_set(os_obj.eid_can, event, TX_OR);
}
